/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <gtest/gtest.h>
#include <test_utilities/test_base.h>

#include "discovery/app_schema.h"
#include "discovery/csr_utils.h"
#include "discovery/object_group_interface.h"

using namespace devmon;

class CsrUtilsTest : public mc::test::TestWithEngine {
public:
    static void SetUpTestSuite() {
        TestWithEngine::SetUpTestSuite();
        std::unordered_map<std::string, std::string> app_paths = {
            {"general_path", "../tests/tests_data/apps/"}};
        app_schema::get_instance().init(app_paths);
    }

    static void TearDownTestSuite() {
        TestWithEngine::TearDownTestSuite();
    }

    void SetUp() override {
        object_group_data::reset_for_test();
    }

    void TearDown() override {
        object_group_data::reset_for_test();
    }
};

// 测试 is_sync 函数
TEST_F(CsrUtilsTest, TestIsSync) {
    EXPECT_TRUE(csr_utils::is_sync("<=/object"));
    EXPECT_TRUE(csr_utils::is_sync("<=/::*object"));
    EXPECT_FALSE(csr_utils::is_sync("#/object"));
    EXPECT_FALSE(csr_utils::is_sync("object"));
    EXPECT_FALSE(csr_utils::is_sync(""));
}

// 测试 is_ref 函数
TEST_F(CsrUtilsTest, TestIsRef) {
    EXPECT_TRUE(csr_utils::is_ref("#/object"));
    EXPECT_TRUE(csr_utils::is_ref("#/::*object"));
    EXPECT_FALSE(csr_utils::is_ref("<=/object"));
    EXPECT_FALSE(csr_utils::is_ref("object"));
    EXPECT_FALSE(csr_utils::is_ref(""));
}

// 测试 get_class_name 函数
TEST_F(CsrUtilsTest, TestGetClassName) {
    EXPECT_EQ(csr_utils::get_class_name("TestObject_1"), "TestObject");
    EXPECT_EQ(csr_utils::get_class_name("TestObject"), "TestObject");
    EXPECT_EQ(csr_utils::get_class_name(""), "");
}

// 测试 is_prop_type_integer 函数
TEST_F(CsrUtilsTest, TestIsPropTypeInteger) {
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "CoolingConfig_1", "SmartCoolingState"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "CoolingConfig_1", "SmartCoolingMode"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "CoolingConfig_1", "LevelPercentRange"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "CoolingConfig_1", "InitLevelInStartup"), true);
    EXPECT_EQ(
        csr_utils::is_prop_type_integer("01", "CoolingConfig_1", "DiskRowTemperatureAvailable"),
        false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "CoolingConfig_1", "SysHDDsMaxTemperature"),
              true);

    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "EventKeyId"),
              false);
    EXPECT_EQ(
        csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "InvalidReadingIgnore"),
        true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "InvalidReading"),
              true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "Condition"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "OperatorId"),
              true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "Enabled"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "Component"),
              false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Event_IEU22_UBNotPresent", "Reading"), false);

    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "FruId"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "Instance"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "Type"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "Name"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "Presence"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "Health"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "PowerState"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "GroupId"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "UniqueId"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "BoardId"), true);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "Component_Chassis", "NodeId"), false);

    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "SRUpgrade_1", "UID"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "SRUpgrade_1", "Type"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "SRUpgrade_1", "Version"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "SRUpgrade_1", "SoftwareId"), false);
    EXPECT_EQ(csr_utils::is_prop_type_integer("01", "SRUpgrade_1", "StorageChip"), false);
}

// 测试 get_sync_targets 函数
TEST_F(CsrUtilsTest, TestGetSyncTargets) {
    auto targets = csr_utils::get_sync_targets("<=/object1.prop1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_FALSE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "object1");
    EXPECT_EQ(targets[0].prop_name, "prop1");

    targets = csr_utils::get_sync_targets("<=/::*object1.prop1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_TRUE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "*object1");
    EXPECT_EQ(targets[0].prop_name, "prop1");

    targets = csr_utils::get_sync_targets("<=/object1.prop1 <=/object2.prop2");
    ASSERT_EQ(targets.size(), 2);
    EXPECT_FALSE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "object1");
    EXPECT_EQ(targets[0].prop_name, "prop1");
    EXPECT_FALSE(targets[1].is_global);
    EXPECT_EQ(targets[1].object_name, "object2");
    EXPECT_EQ(targets[1].prop_name, "prop2");

    targets = csr_utils::get_sync_targets("normal string");
    EXPECT_TRUE(targets.empty());
}

// 测试 get_ref_targets 函数
TEST_F(CsrUtilsTest, TestGetRefTargets) {
    auto targets = csr_utils::get_ref_targets("#/object1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_FALSE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "object1");
    EXPECT_EQ(targets[0].prop_name, "");

    targets = csr_utils::get_ref_targets("#/::*object1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_TRUE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "*object1");
    EXPECT_EQ(targets[0].prop_name, "");

    targets = csr_utils::get_ref_targets("#/object1.prop1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_FALSE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "object1");
    EXPECT_EQ(targets[0].prop_name, "prop1");

    targets = csr_utils::get_ref_targets("normal string");
    EXPECT_TRUE(targets.empty());
}

// 测试 replace_sync_objects 函数
TEST_F(CsrUtilsTest, TestReplaceSyncObjects) {
    string_map_t objects_map = {
        {"object1", "object1_new"}, {"object2", "object2_new"}, {"Power_1", "Power_1_0101"}};

    EXPECT_EQ(csr_utils::replace_sync_objects("<=/object1.prop1", objects_map),
              "<=/object1_new.prop1");
    EXPECT_EQ(csr_utils::replace_sync_objects("<=/object2.prop2", objects_map),
              "<=/object2_new.prop2");
    EXPECT_EQ(csr_utils::replace_sync_objects("<=/object3.prop3", objects_map), "<=/object3.prop3");
    EXPECT_EQ(csr_utils::replace_sync_objects("normal string", objects_map), "normal string");
    EXPECT_EQ(csr_utils::replace_sync_objects("<=/Power_1.prop1;<=/Power_1.prop2 |> expr($1 + $2)",
                                              objects_map),
              "<=/Power_1_0101.prop1;<=/Power_1_0101.prop2 |> expr($1 + $2)");
}

// 测试 replace_ref_object 函数
TEST_F(CsrUtilsTest, TestReplaceRefObject) {
    string_map_t objects_map = {{"object1", "object1_new"}, {"object2", "object2_new"}};

    EXPECT_EQ(csr_utils::replace_ref_object("#/object1", objects_map), "#/object1_new");
    EXPECT_EQ(csr_utils::replace_ref_object("#/object2", objects_map), "#/object2_new");
    EXPECT_EQ(csr_utils::replace_ref_object("#/object3", objects_map), "#/object3");
    EXPECT_EQ(csr_utils::replace_ref_object("normal string", objects_map), "normal string");
}

// 测试 convert_topology 函数
TEST_F(CsrUtilsTest, TestConvertTopology) {
    std::string topo_str = R"({
        "Anchor": {
            "Buses": [
                "I2c_1"
            ]
        },
        "I2c_1": {
            "Connectors": [
                "Connector_1"
            ]
        }
    })";
    auto        topology = csr_utils::convert_topology(mc::json::json_decode(topo_str).as_dict());
    std::string expected_str      = R"({
        "Anchor": [
            "I2c_1"
        ],
        "I2c_1": [
            "Connector_1"
        ]
    })";
    auto        expected_topology = mc::json::json_decode(expected_str).as_dict();
    EXPECT_EQ(topology, expected_topology);
}

// 测试 get_prop_expr 函数
TEST_F(CsrUtilsTest, TestGetPropExpr) {
    auto exprs = csr_utils::get_prop_expr("#/Smc_ExpBoardSMC", 10);
    EXPECT_EQ(exprs.size(), 0);
    exprs = csr_utils::get_prop_expr("<=/Scanner_HddBPPresent.Value", 10);
    EXPECT_EQ(exprs.size(), 0);
    exprs = csr_utils::get_prop_expr(
        "<=/Scanner_SerdesLom1Pres.Value |> expr(($1 > 0) ? 4.2 : 5.8)", 10);
    EXPECT_EQ(exprs.size(), 1);
    EXPECT_EQ(exprs[0], "\"expr(($1 > 0) ? 4.2 : 5.8)\"");
    exprs = csr_utils::get_prop_expr(
        "${Slot} |> expr($1 * 2 - 1) |> string.format('CPU%s MEM Temp', $1)", 10);
    EXPECT_EQ(exprs.size(), 2);
    EXPECT_EQ(exprs[0], "\"expr($1 * 2 - 1)\"");
    EXPECT_EQ(exprs[1], "\"string.format('CPU%s MEM Temp', $1)\"");
}

// 测试 is_ref_presence 函数
TEST_F(CsrUtilsTest, TestIsRefPresence) {
    EXPECT_TRUE(csr_utils::is_ref_presence("#/object", "Connector", "Presence"));
    EXPECT_FALSE(csr_utils::is_ref_presence("<=/object", "Connector", "Presence"));
    EXPECT_FALSE(csr_utils::is_ref_presence("#/object", "Component", "Presence"));
    EXPECT_FALSE(csr_utils::is_ref_presence("#/object", "Connector", "OtherProp"));
    EXPECT_FALSE(csr_utils::is_ref_presence("normal", "Connector", "Presence"));
}

// 测试 is_func_call 函数
TEST_F(CsrUtilsTest, TestIsFuncCall) {
    EXPECT_TRUE(csr_utils::is_func_call("$Func_test({})"));
    EXPECT_TRUE(csr_utils::is_func_call("$Func_calculate({x: 1})"));
    EXPECT_FALSE(csr_utils::is_func_call("Func_test({})"));
    EXPECT_FALSE(csr_utils::is_func_call("#/object"));
    EXPECT_FALSE(csr_utils::is_func_call("<=/object"));
    EXPECT_FALSE(csr_utils::is_func_call("normal string"));
    EXPECT_FALSE(csr_utils::is_func_call(""));
}

// 测试 get_sync_targets 函数带接口名
TEST_F(CsrUtilsTest, TestGetSyncTargetsWithInterface) {
    auto targets = csr_utils::get_sync_targets("<=/object1[interface.name].prop1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_FALSE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "object1");
    EXPECT_EQ(targets[0].interface_name, "interface.name");
    EXPECT_EQ(targets[0].prop_name, "prop1");

    targets = csr_utils::get_sync_targets("<=/::*object1[bmc.dev.Interface].prop1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_TRUE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "*object1");
    EXPECT_EQ(targets[0].interface_name, "bmc.dev.Interface");
    EXPECT_EQ(targets[0].prop_name, "prop1");
}

// 测试 get_ref_targets 函数带接口名
TEST_F(CsrUtilsTest, TestGetRefTargetsWithInterface) {
    auto targets = csr_utils::get_ref_targets("#/object1[interface.name].prop1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_FALSE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "object1");
    EXPECT_EQ(targets[0].interface_name, "interface.name");
    EXPECT_EQ(targets[0].prop_name, "prop1");

    targets = csr_utils::get_ref_targets("#/::*object1[bmc.dev.Interface].prop1");
    ASSERT_EQ(targets.size(), 1);
    EXPECT_TRUE(targets[0].is_global);
    EXPECT_EQ(targets[0].object_name, "*object1");
    EXPECT_EQ(targets[0].interface_name, "bmc.dev.Interface");
    EXPECT_EQ(targets[0].prop_name, "prop1");
}

// 测试 replace_sync_objects 函数处理全局标记
TEST_F(CsrUtilsTest, TestReplaceSyncObjectsWithGlobal) {
    string_map_t objects_map = {{"object1", "object1_new"}};

    // 全局标记的对象不应该被替换
    EXPECT_EQ(csr_utils::replace_sync_objects("<=/::*object1.prop1", objects_map),
              "<=/::*object1.prop1");
    EXPECT_EQ(csr_utils::replace_sync_objects("<=/object1.prop1 <=/::*object1.prop1", objects_map),
              "<=/object1_new.prop1 <=/::*object1.prop1");
}

// 测试 replace_sync_objects 函数处理同名对象多次出现
TEST_F(CsrUtilsTest, TestReplaceSyncObjectsMultipleOccurrences) {
    string_map_t objects_map = {{"object1", "object1_new"}};

    // 同一个对象名出现多次，应该只替换一次
    std::string result = csr_utils::replace_sync_objects(
        "<=/object1.prop1 <=/object1.prop2 <=/object1.prop3", objects_map);
    EXPECT_EQ(result, "<=/object1_new.prop1 <=/object1_new.prop2 <=/object1_new.prop3");
}

// 测试 replace_ref_object 函数处理全局标记
TEST_F(CsrUtilsTest, TestReplaceRefObjectWithGlobal) {
    string_map_t objects_map = {{"object1", "object1_new"}};

    // 全局标记的对象不应该被替换
    EXPECT_EQ(csr_utils::replace_ref_object("#/::*object1", objects_map), "#/::*object1");
    // 注意：replace_ref_object只处理单个引用值
    EXPECT_EQ(csr_utils::replace_ref_object("#/object1", objects_map), "#/object1_new");
}

// 测试 replace_ref_object 函数处理多次出现
TEST_F(CsrUtilsTest, TestReplaceRefObjectMultipleOccurrences) {
    string_map_t objects_map = {{"object1", "object1_new"}};

    // replace_ref_object只处理单个引用值，这里测试带属性的引用
    std::string result = csr_utils::replace_ref_object("#/object1.prop1", objects_map);
    EXPECT_EQ(result, "#/object1_new.prop1");
}

// 测试 get_prop_expr 函数边界情况
TEST_F(CsrUtilsTest, TestGetPropExprEdgeCases) {
    // 测试空字符串
    auto exprs = csr_utils::get_prop_expr("", 10);
    EXPECT_EQ(exprs.size(), 0);

    // 测试无表达式的字符串
    exprs = csr_utils::get_prop_expr("normal text", 10);
    EXPECT_EQ(exprs.size(), 0);

    // 测试表达式级别限制
    EXPECT_THROW(csr_utils::get_prop_expr("value |> expr1 |> expr2 |> expr3 |> expr4 |> expr5 |> "
                                          "expr6 |> expr7 |> expr8 |> expr9 |> expr10 |> expr11",
                                          10),
                 mc::parse_error_exception);

    // 测试不限制表达式数量
    exprs = csr_utils::get_prop_expr("${Slot} |> expr1 |> expr2 |> expr3", -1);
    EXPECT_EQ(exprs.size(), 3);
}

// 测试 convert_topology 函数多级递归场景（与topology.sr相同结构）
TEST_F(CsrUtilsTest, TestConvertTopologyComplex) {
    std::string topo_str = R"({
        "Anchor": {
            "Buses": [
                "Bus_I2c_1",
                "Bus_I2c_2"
            ]
        },
        "Bus_I2c_1": {
            "Chips": [
                "Chip_1",
                "Pca9545_1"
            ]
        },
        "Bus_I2c_2": {
            "Chips": [
                "Chip_3",
                "Chip_4"
            ]
        },
        "Pca9545_1": {
            "Buses": [
                "I2c_Mux_1"
            ]
        },
        "I2c_Mux_1": {
            "Chips": [
                "Chip_5"
            ]
        }
    })";
    auto        topology = csr_utils::convert_topology(mc::json::json_decode(topo_str).as_dict());

    // 验证Anchor包含Bus_I2c_1和Bus_I2c_2
    EXPECT_TRUE(topology.contains("Anchor"));
    auto anchor_buses = topology["Anchor"].as<std::vector<std::string>>();
    EXPECT_EQ(anchor_buses.size(), 2);

    // 验证Bus_I2c_1包含Chip_1和Pca9545_1
    EXPECT_TRUE(topology.contains("Bus_I2c_1"));
    auto i2c1_chips = topology["Bus_I2c_1"].as<std::vector<std::string>>();
    EXPECT_EQ(i2c1_chips.size(), 2);

    // 验证Bus_I2c_2包含Chip_3和Chip_4
    EXPECT_TRUE(topology.contains("Bus_I2c_2"));
    auto i2c2_chips = topology["Bus_I2c_2"].as<std::vector<std::string>>();
    EXPECT_EQ(i2c2_chips.size(), 2);

    // 验证递归处理Pca9545_1 -> I2c_Mux_1 -> Chip_5
    // 注意：Chip_5没有子节点，所以不会在topology中出现
    EXPECT_TRUE(topology.contains("Pca9545_1"));
    EXPECT_TRUE(topology.contains("I2c_Mux_1"));
    // Chip_5没有Buses或Chips，所以不会出现在converted_topology中
    EXPECT_FALSE(topology.contains("Chip_5"));
}

// 测试 convert_topology 函数空和无效输入
TEST_F(CsrUtilsTest, TestConvertTopologyEdgeCases) {
    // 测试空拓扑
    mc::dict empty_topology;
    auto     result = csr_utils::convert_topology(empty_topology);
    EXPECT_TRUE(result.empty());

    // 测试无Anchor的拓扑
    std::string topo_str = R"({
        "I2c_1": {
            "Chips": ["Chip_1"]
        }
    })";
    result               = csr_utils::convert_topology(mc::json::json_decode(topo_str).as_dict());
    EXPECT_TRUE(result.empty());
}

// 测试 get_class_name 函数边界情况
TEST_F(CsrUtilsTest, TestGetClassNameEdgeCases) {
    EXPECT_EQ(csr_utils::get_class_name("Object_"), "Object");
    EXPECT_EQ(csr_utils::get_class_name("_Object"), "");
    EXPECT_EQ(csr_utils::get_class_name("Object_1_2"), "Object");
    EXPECT_EQ(csr_utils::get_class_name("Test_Object_1"), "Test");
}

// 测试 get_connector_position 函数
TEST_F(CsrUtilsTest, TestGetConnectorPosition) {
    // 测试整数位置
    mc::dict    connector1 = {{"GroupPosition", 26}};
    std::string pos1       = csr_utils::get_connector_position(connector1);
    EXPECT_EQ(pos1, "1A");

    // 测试字符串位置
    mc::dict    connector2 = {{"GroupPosition", "1A"}};
    std::string pos2       = csr_utils::get_connector_position(connector2);
    EXPECT_EQ(pos2, "1A");

    // 测试无GroupPosition
    mc::dict    connector3 = {{"Position", "01"}};
    std::string pos3       = csr_utils::get_connector_position(connector3);
    EXPECT_EQ(pos3, "");

    // 测试空connector
    mc::dict    connector4;
    std::string pos4 = csr_utils::get_connector_position(connector4);
    EXPECT_EQ(pos4, "");

    // 测试奇数长度整数位置
    mc::dict    connector5 = {{"GroupPosition", 5}};
    std::string pos5       = csr_utils::get_connector_position(connector5);
    EXPECT_EQ(pos5, "05");
}

// 测试 get_instance_info 函数
TEST_F(CsrUtilsTest, TestGetInstanceInfo) {
    mc::dict variable_map = {{"SystemId", 1}, {"Id", "101"}};

    // 测试从schema获取实例信息
    instance_info_t info = csr_utils::get_instance_info("0101", "Component_Chassis", variable_map);
    EXPECT_FALSE(info.app.empty());
    EXPECT_FALSE(info.path.empty());

    // 测试不存在的类
    info = csr_utils::get_instance_info("0101", "NonExistent_1", variable_map);
    EXPECT_TRUE(info.app.empty());
    EXPECT_TRUE(info.path.empty());
}

// 测试 get_property_intf 函数（基于schema）
TEST_F(CsrUtilsTest, TestGetPropertyIntfFromSchema) {
    // 测试存在的类和属性
    auto [intf, prop_name] = csr_utils::get_property_intf("0101", "Component_Chassis", "FruId");
    EXPECT_FALSE(intf.empty());

    // 测试不存在的类
    std::tie(intf, prop_name) = csr_utils::get_property_intf("0101", "NonExistent_1", "Prop");
    EXPECT_TRUE(intf.empty());

    // 测试不存在的属性
    std::tie(intf, prop_name) =
        csr_utils::get_property_intf("0101", "Component_Chassis", "NonExistent");
    EXPECT_TRUE(intf.empty());
}

// 测试 get_property_intf 函数（基于ref_sync_target）
TEST_F(CsrUtilsTest, TestGetPropertyIntfFromTarget) {
    // 测试带接口名的target
    ref_sync_target target1;
    target1.interface_name = "bmc.dev.Interface";
    target1.prop_name      = "PropertyName";
    auto [intf1, prop1]    = csr_utils::get_property_intf("0101", target1);
    EXPECT_EQ(intf1, "bmc.dev.Interface");
    EXPECT_EQ(prop1, "PropertyName");

    // 测试不带接口名的target
    ref_sync_target target2;
    target2.object_name = "Component_Chassis";
    target2.prop_name   = "FruId";
    auto [intf2, prop2] = csr_utils::get_property_intf("0101", target2);
    // 应该从schema获取接口名和属性名
    EXPECT_FALSE(intf2.empty());
    EXPECT_FALSE(prop2.empty());
}

// 测试 object_group_data::save_objects 和 get_objects
TEST_F(CsrUtilsTest, TestObjectGroupDataSaveAndGet) {
    std::vector<std::shared_ptr<parsed_sr_object>>      parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    // 创建测试对象
    auto obj1          = std::make_shared<parsed_sr_object>();
    obj1->app_name     = "test_app";
    obj1->class_name   = "TestClass";
    obj1->object_name  = "TestObject_1_0101";
    obj1->object_props = mc::mutable_dict{{"Prop1", "Value1"}};
    parsed_objects.push_back(obj1);

    auto obj2          = std::make_shared<parsed_sr_object>();
    obj2->app_name     = "another_app";
    obj2->class_name   = "AnotherClass";
    obj2->object_name  = "AnotherObject_1_0101";
    obj2->object_props = mc::mutable_dict{{"Prop2", "Value2"}};
    parsed_objects.push_back(obj2);

    // 保存对象
    object_group_data::get_instance().save_objects("0101", parsed_objects, parsed_func_objects);

    // 获取对象
    auto objects1 = object_group_data::get_instance().get_objects("0101", "test_app");
    EXPECT_EQ(objects1.Position, "0101");
    EXPECT_EQ(objects1.Objects.size(), 1);
    EXPECT_EQ(objects1.Objects[0].ClassName, "TestClass");
    EXPECT_EQ(objects1.Objects[0].ObjectName, "TestObject_1_0101");

    auto objects2 = object_group_data::get_instance().get_objects("0101", "another_app");
    EXPECT_EQ(objects2.Objects.size(), 1);
    EXPECT_EQ(objects2.Objects[0].ClassName, "AnotherClass");

    // 测试不存在的owner
    auto objects3 = object_group_data::get_instance().get_objects("0101", "nonexistent");
    EXPECT_EQ(objects3.Objects.size(), 0);
}

// 测试 object_group_data::save_topology 和 get_topology
TEST_F(CsrUtilsTest, TestObjectGroupDataTopology) {
    mc::dict topology = {{"Anchor", mc::variants{"I2c_1"}}, {"I2c_1", mc::variants{"Chip_1"}}};

    // 保存拓扑
    object_group_data::get_instance().save_topology("0101", topology);

    // 获取拓扑
    auto retrieved = object_group_data::get_instance().get_topology("0101");
    EXPECT_EQ(retrieved, topology);

    // 测试不存在的position
    auto empty = object_group_data::get_instance().get_topology("9999");
    EXPECT_TRUE(empty.empty());
}

// 测试 object_group_data::get_owners
TEST_F(CsrUtilsTest, TestObjectGroupDataGetOwners) {
    std::vector<std::shared_ptr<parsed_sr_object>>      parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    auto obj1          = std::make_shared<parsed_sr_object>();
    obj1->app_name     = "app1";
    obj1->class_name   = "Class1";
    obj1->object_name  = "Object1_0101";
    obj1->object_props = mc::mutable_dict{};
    parsed_objects.push_back(obj1);

    auto obj2          = std::make_shared<parsed_sr_object>();
    obj2->app_name     = "app2";
    obj2->class_name   = "Class2";
    obj2->object_name  = "Object2_0101";
    obj2->object_props = mc::mutable_dict{};
    parsed_objects.push_back(obj2);

    object_group_data::get_instance().save_objects("0101", parsed_objects, parsed_func_objects);

    auto owners = object_group_data::get_instance().get_owners("0101");
    EXPECT_EQ(owners.size(), 2);
    EXPECT_EQ(std::find(owners.begin(), owners.end(), "app1") != owners.end(), true);
    EXPECT_EQ(std::find(owners.begin(), owners.end(), "app2") != owners.end(), true);

    // 测试不存在的position
    auto empty_owners = object_group_data::get_instance().get_owners("9999");
    EXPECT_TRUE(empty_owners.empty());
}

// 测试 object_group_data::save_device_object 和相关方法
TEST_F(CsrUtilsTest, TestObjectGroupDataDeviceObjects) {
    // 注意：这个测试需要实际的设备对象，可能需要在集成测试中完成
    // 这里主要测试接口是否存在
    EXPECT_FALSE(object_group_data::get_instance().is_device_object("0101", "TestDevice"));
    EXPECT_EQ(object_group_data::get_instance().get_device_object("0101", "TestDevice"), nullptr);

    // 清理设备对象
    object_group_data::get_instance().clear_device_objects("0101");
    EXPECT_FALSE(object_group_data::get_instance().is_device_object("0101", "TestDevice"));
}

// 测试 object_group_data::save_objects 处理函数对象
TEST_F(CsrUtilsTest, TestObjectGroupDataWithFuncObjects) {
    std::vector<std::shared_ptr<parsed_sr_object>>      parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    // 创建一个普通对象以触发保存逻辑
    auto obj          = std::make_shared<parsed_sr_object>();
    obj->app_name     = "app1";
    obj->class_name   = "TestClass";
    obj->object_name  = "Object_1_0101";
    obj->object_props = mc::mutable_dict{};
    parsed_objects.push_back(obj);

    // 创建函数对象，分发给多个应用
    auto func_obj          = std::make_shared<parsed_sr_func_object>();
    func_obj->app_names    = {"app1", "app2"};
    func_obj->class_name   = "Func";
    func_obj->object_name  = "Func_test_0101";
    func_obj->object_props = mc::mutable_dict{{"result", "test"}};
    parsed_func_objects.push_back(func_obj);

    object_group_data::get_instance().save_objects("0101", parsed_objects, parsed_func_objects);

    // 验证函数对象出现在两个应用中
    auto objects1 = object_group_data::get_instance().get_objects("0101", "app1");
    EXPECT_EQ(objects1.Objects.size(), 2); // 1个普通对象 + 1个函数对象
    EXPECT_EQ(objects1.Objects[0].ClassName, "TestClass");
    EXPECT_EQ(objects1.Objects[1].ClassName, "Func");

    auto objects2 = object_group_data::get_instance().get_objects("0101", "app2");
    EXPECT_EQ(objects2.Objects.size(), 1);
    EXPECT_EQ(objects2.Objects[0].ClassName, "Func");
}

// 测试 object_group_data::save_objects 处理Connector类的SystemId
TEST_F(CsrUtilsTest, TestObjectGroupDataConnectorSystemId) {
    std::vector<std::shared_ptr<parsed_sr_object>>      parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    auto connector          = std::make_shared<parsed_sr_object>();
    connector->app_name     = "test_app";
    connector->class_name   = "Connector";
    connector->object_name  = "Connector_1_0101";
    connector->object_props = mc::mutable_dict{{"SystemId", "1"}};
    parsed_objects.push_back(connector);

    object_group_data::get_instance().save_objects("0101", parsed_objects, parsed_func_objects);

    auto objects = object_group_data::get_instance().get_objects("0101", "test_app");
    ASSERT_EQ(objects.Objects.size(), 1);
    auto props = mc::json::json_decode(objects.Objects[0].ObjectProps).as_dict();
    // SystemId应该被转换为整型
    EXPECT_TRUE(props["SystemId"].is_numeric());
    EXPECT_EQ(props["SystemId"].as_int64(), 1);
}

// 测试 convert_topology 函数处理空数组
TEST_F(CsrUtilsTest, TestConvertTopologyEmptyArrays) {
    std::string topo_str = R"({
        "Anchor": {
            "Buses": []
        },
        "I2c_1": {
            "Chips": []
        }
    })";
    auto        topology = csr_utils::convert_topology(mc::json::json_decode(topo_str).as_dict());
    // 空数组应该被忽略
    EXPECT_FALSE(topology.contains("Anchor"));
    EXPECT_FALSE(topology.contains("I2c_1"));
}

// 测试 object_group_data::save_objects LifeCycleId递增
TEST_F(CsrUtilsTest, TestObjectGroupDataLifeCycleId) {
    std::vector<std::shared_ptr<parsed_sr_object>>      parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    auto obj1          = std::make_shared<parsed_sr_object>();
    obj1->app_name     = "test_app";
    obj1->class_name   = "TestClass";
    obj1->object_name  = "Object1_0101";
    obj1->object_props = mc::mutable_dict{};
    parsed_objects.push_back(obj1);

    // 第一次保存
    object_group_data::get_instance().save_objects("0101", parsed_objects, parsed_func_objects);
    auto objects1 = object_group_data::get_instance().get_objects("0101", "test_app");
    EXPECT_EQ(objects1.LifeCycleId, 1);

    // 第二次保存，LifeCycleId应该递增
    auto obj2          = std::make_shared<parsed_sr_object>();
    obj2->app_name     = "test_app";
    obj2->class_name   = "TestClass";
    obj2->object_name  = "Object2_0101";
    obj2->object_props = mc::mutable_dict{};
    std::vector<std::shared_ptr<parsed_sr_object>> parsed_objects2;
    parsed_objects2.push_back(obj2);
    object_group_data::get_instance().save_objects("0101", parsed_objects2, parsed_func_objects);
    auto objects2 = object_group_data::get_instance().get_objects("0101", "test_app");
    EXPECT_EQ(objects2.LifeCycleId, 2);
}

// 测试 object_group_data::save_objects 处理空对象列表
TEST_F(CsrUtilsTest, TestObjectGroupDataEmptyObjects) {
    std::vector<std::shared_ptr<parsed_sr_object>>      parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    // 保存空列表不应该出错
    object_group_data::get_instance().save_objects("0101", parsed_objects, parsed_func_objects);
    auto objects = object_group_data::get_instance().get_objects("0101", "test_app");
    EXPECT_EQ(objects.Objects.size(), 0);
}

// 测试 object_group_data::save_objects 处理extra_props
TEST_F(CsrUtilsTest, TestObjectGroupDataExtraProps) {
    std::vector<std::shared_ptr<parsed_sr_object>>      parsed_objects;
    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    auto obj          = std::make_shared<parsed_sr_object>();
    obj->app_name     = "test_app";
    obj->class_name   = "TestClass";
    obj->object_name  = "Object_0101";
    obj->object_props = mc::mutable_dict{{"Prop1", "Value1"}};
    obj->extra_props  = mc::mutable_dict{{"Path", "/test/path"}, {"@Parent", "/parent/path"}};
    parsed_objects.push_back(obj);

    object_group_data::get_instance().save_objects("0101", parsed_objects, parsed_func_objects);
    auto objects = object_group_data::get_instance().get_objects("0101", "test_app");
    ASSERT_EQ(objects.Objects.size(), 1);

    // 验证ObjectExtends包含extra_props
    auto extends = mc::json::json_decode(objects.Objects[0].ObjectExtends).as_dict();
    EXPECT_TRUE(extends.contains("Path"));
    EXPECT_TRUE(extends.contains("@Parent"));
}

// 测试 get_instance_info 函数处理device object
TEST_F(CsrUtilsTest, TestGetInstanceInfoWithDeviceObject) {
    // 注意：这个测试需要实际的device object，可能需要在集成测试中完成
    // 这里主要测试接口是否正常工作
    mc::dict        variable_map = {{"SystemId", 1}};
    instance_info_t info = csr_utils::get_instance_info("0101", "Component_Chassis", variable_map);
    EXPECT_FALSE(info.app.empty());
}

// 测试 get_property_intf 函数处理不存在的对象
// 测试 object_group_interface GetObjects 方法
TEST_F(CsrUtilsTest, TestObjectGroupInterfaceGetObjects) {
    object_group_data::reset_for_test();

    // 准备测试数据
    std::string position = "0101";
    std::string owner    = "test_devices";

    std::vector<std::shared_ptr<parsed_sr_object>> parsed_objects;
    auto                                           obj1 = std::make_shared<parsed_sr_object>();
    obj1->app_name                                      = owner;
    obj1->class_name                                    = "TestCard";
    obj1->object_name                                   = "TestCard_1_0101";
    obj1->object_props                                  = mc::mutable_dict{{"DeviceName", "test1"}};
    parsed_objects.push_back(obj1);

    auto obj2          = std::make_shared<parsed_sr_object>();
    obj2->app_name     = owner;
    obj2->class_name   = "TestCard";
    obj2->object_name  = "TestCard_2_0101";
    obj2->object_props = mc::mutable_dict{{"DeviceName", "test2"}};
    parsed_objects.push_back(obj2);

    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;
    object_group_data::get_instance().save_objects(position, parsed_objects, parsed_func_objects);

    // 创建对象组接口（模拟）
    object_group_t object_group = object_group_data::get_instance().get_objects(position, owner);
    EXPECT_EQ(object_group.Position, position);
    EXPECT_EQ(object_group.Objects.size(), 2);
    EXPECT_EQ(object_group.Objects[0].ObjectName, "TestCard_1_0101");
    EXPECT_EQ(object_group.Objects[1].ObjectName, "TestCard_2_0101");
}

// 测试 object_group_interface GetObjects 空 owner
TEST_F(CsrUtilsTest, TestObjectGroupInterfaceGetObjectsEmptyOwner) {
    object_group_data::reset_for_test();

    std::string position = "0101";
    std::string owner    = "nonexistent_owner";

    object_group_t object_group = object_group_data::get_instance().get_objects(position, owner);
    // 当 owner 不存在时，get_objects 返回空的 object_group_t{}，Position 字段是空字符串
    EXPECT_EQ(object_group.Position, "");
    EXPECT_EQ(object_group.Objects.size(), 0);
}

// 测试 object_group_interface GetTopology
TEST_F(CsrUtilsTest, TestObjectGroupInterfaceGetTopology) {
    object_group_data::reset_for_test();

    std::string position = "0101";
    mc::dict    topology = {{"Anchor", mc::dict{{"Buses", mc::variants{"I2c_1"}}}}};

    object_group_data::get_instance().save_topology(position, topology);

    mc::dict retrieved_topology = object_group_data::get_instance().get_topology(position);
    EXPECT_TRUE(retrieved_topology.contains("Anchor"));
    if (retrieved_topology.contains("Anchor")) {
        auto anchor = retrieved_topology["Anchor"].as_dict();
        EXPECT_TRUE(anchor.contains("Buses"));
    }
}

// 测试 object_group_interface GetTopology 不存在的位置
TEST_F(CsrUtilsTest, TestObjectGroupInterfaceGetTopologyNonExistent) {
    object_group_data::reset_for_test();

    std::string position = "nonexistent";

    mc::dict retrieved_topology = object_group_data::get_instance().get_topology(position);
    EXPECT_TRUE(retrieved_topology.empty());
}

// 测试 object_group_data 并发访问
TEST_F(CsrUtilsTest, TestObjectGroupDataConcurrentAccess) {
    object_group_data::reset_for_test();

    std::string position = "0101";
    std::string owner    = "test_devices";

    // 模拟并发写入
    std::vector<std::shared_ptr<parsed_sr_object>> parsed_objects1;
    auto                                           obj1 = std::make_shared<parsed_sr_object>();
    obj1->app_name                                      = owner;
    obj1->class_name                                    = "TestCard";
    obj1->object_name                                   = "TestCard_1_0101";
    obj1->object_props                                  = mc::mutable_dict{{"DeviceName", "test1"}};
    parsed_objects1.push_back(obj1);

    std::vector<std::shared_ptr<parsed_sr_object>> parsed_objects2;
    auto                                           obj2 = std::make_shared<parsed_sr_object>();
    obj2->app_name                                      = owner;
    obj2->class_name                                    = "TestCard";
    obj2->object_name                                   = "TestCard_2_0101";
    obj2->object_props                                  = mc::mutable_dict{{"DeviceName", "test2"}};
    parsed_objects2.push_back(obj2);

    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;

    // 并发保存
    object_group_data::get_instance().save_objects(position, parsed_objects1, parsed_func_objects);
    object_group_data::get_instance().save_objects(position, parsed_objects2, parsed_func_objects);

    // 验证数据一致性
    object_group_t object_group = object_group_data::get_instance().get_objects(position, owner);
    EXPECT_EQ(object_group.Position, position);
    // 应该包含两个对象（或者最后一个保存的结果）
    EXPECT_GE(object_group.Objects.size(), 1);
}

// 测试 object_group_data get_owners 多个 owner
TEST_F(CsrUtilsTest, TestObjectGroupDataMultipleOwners) {
    object_group_data::reset_for_test();

    std::string position = "0101";

    // 注意：save_objects 每次调用会完全替换该 position 的所有数据
    // 所以要在一次调用中保存多个 owner 的对象
    std::vector<std::shared_ptr<parsed_sr_object>> objects;
    auto                                           obj1 = std::make_shared<parsed_sr_object>();
    obj1->app_name                                      = "owner1";
    obj1->class_name                                    = "TestCard";
    obj1->object_name                                   = "TestCard_1_0101";
    obj1->object_props                                  = mc::mutable_dict{{"DeviceName", "test1"}};
    objects.push_back(obj1);

    auto obj2          = std::make_shared<parsed_sr_object>();
    obj2->app_name     = "owner2";
    obj2->class_name   = "TestCard";
    obj2->object_name  = "TestCard_2_0101";
    obj2->object_props = mc::mutable_dict{{"DeviceName", "test2"}};
    objects.push_back(obj2);

    std::vector<std::shared_ptr<parsed_sr_func_object>> parsed_func_objects;
    // 在一次调用中保存多个 owner 的对象
    object_group_data::get_instance().save_objects(position, objects, parsed_func_objects);

    auto owners = object_group_data::get_instance().get_owners(position);
    EXPECT_EQ(owners.size(), 2);
    EXPECT_TRUE(std::find(owners.begin(), owners.end(), "owner1") != owners.end());
    EXPECT_TRUE(std::find(owners.begin(), owners.end(), "owner2") != owners.end());
}

// 测试 object_group_data 设备对象管理
TEST_F(CsrUtilsTest, TestObjectGroupDataDeviceObjectManagement) {
    object_group_data::reset_for_test();

    std::string position    = "0101";
    std::string object_name = "TestDevice_1";

    // 注意：这里无法直接创建 abstract_object，需要模拟
    // 实际测试中应该通过 device_manager 来创建设备对象

    // 测试 is_device_object 和 get_device_object
    bool is_device = object_group_data::get_instance().is_device_object(position, object_name);
    EXPECT_FALSE(is_device); // 对象不存在

    auto device_obj = object_group_data::get_instance().get_device_object(position, object_name);
    EXPECT_EQ(device_obj, nullptr);
}

// 测试 object_group_data clear_device_objects
TEST_F(CsrUtilsTest, TestObjectGroupDataClearDeviceObjects) {
    object_group_data::reset_for_test();

    std::string position = "0101";

    // 清空设备对象应该不会抛出异常
    EXPECT_NO_THROW(object_group_data::get_instance().clear_device_objects(position));
}

TEST_F(CsrUtilsTest, TestGetPropertyIntfNonExistentObject) {
    auto [intf, prop_name] = csr_utils::get_property_intf("9999", "NonExistent_9999", "Prop");
    EXPECT_TRUE(intf.empty());
    EXPECT_TRUE(prop_name.empty());
}

TEST_F(CsrUtilsTest, TestGetLocalRefObjectInfo) {
    auto ref_info = csr_utils::get_local_ref_object_info("Event_CPUPresence");
    EXPECT_EQ(ref_info, R"({"ObjectName":"Event_CPUPresence","type":"local reference object"})");
    ref_info = csr_utils::get_local_ref_object_info("");
    EXPECT_EQ(ref_info, R"({"ObjectName":"","type":"local reference object"})");
}

TEST_F(CsrUtilsTest, TestGetRemoteRefObjectInfo) {
    auto ref_info = csr_utils::get_remote_ref_object_info("test_service", "/bmc/kepler/TestObj");
    EXPECT_EQ(ref_info,
              R"({"Object":{"Service":"bmc.kepler.test_service","Path":"/bmc/kepler/TestObj"},)"
              R"("type":"remote reference object"})");
    ref_info = csr_utils::get_remote_ref_object_info("abc", "");
    EXPECT_EQ(
        ref_info,
        R"({"Object":{"Service":"bmc.kepler.abc","Path":""},"type":"remote reference object"})");
}

TEST_F(CsrUtilsTest, TestGetLocalRefPropertyInfo) {
    auto ref_info = csr_utils::get_local_ref_property_info(
        "Event_CPUPresence", "Reading", ",\"expressions\":[\"expr(($1 > 0) ? 4.2 : 5.8)\"]");
    EXPECT_EQ(
        ref_info,
        R"({"source":{"properties":[{"ObjectName":"Event_CPUPresence","Property":"Reading"}],)"
        R"#("expressions":["expr(($1 > 0) ? 4.2 : 5.8)"]},"type":"local reference property"})#");
    ref_info = csr_utils::get_local_ref_property_info("", "", "");
    EXPECT_EQ(
        ref_info,
        R"({"source":{"properties":[{"ObjectName":"","Property":""}]},"type":"local reference property"})");
}

TEST_F(CsrUtilsTest, TestGetRemoteRefPropertyInfo) {
    auto ref_info = csr_utils::get_remote_ref_property_info(
        "test_service", "/bmc/kepler/TestObj", "bmc.kepler.TestInterface", "TestProp",
        ",\"expressions\":[\"expr(($1 > 0) ? 4.2 : 5.8)\"]");
    EXPECT_EQ(
        ref_info,
        R"({"source":{"properties":[{"Service":"bmc.kepler.test_service","Path":"/bmc/kepler/TestObj",)"
        R"("Interface":"bmc.kepler.TestInterface","Property":"TestProp"}],)"
        R"#("expressions":["expr(($1 > 0) ? 4.2 : 5.8)"]},"type":"remote reference property"})#");
    ref_info = csr_utils::get_remote_ref_property_info("abc", "", "", "", "");
    EXPECT_EQ(
        ref_info,
        R"({"source":{"properties":[{"Service":"bmc.kepler.abc","Path":"","Interface":"","Property":""}]},)"
        R"("type":"remote reference property"})");
}

TEST_F(CsrUtilsTest, TestGetSyncPropertyInfo) {
    std::vector<std::tuple<std::string, std::string, std::string, std::string>> properties = {
        {"bmc.kepler.service_1", "/bmc/kepler/TestObj1", "bmc.kepler.TestInterface1", "TestProp1"},
        {"bmc.kepler.service_2", "/bmc/kepler/TestObj2", "bmc.kepler.TestInterface2", "TestProp2"},
    };
    auto sync_info = csr_utils::get_sync_property_info(",\"expressions\":[\"expr($1 + $2 * 3)\"]",
                                                       ",\"Default\":3.14", properties);
    EXPECT_EQ(
        sync_info,
        R"({"properties":[{"Service":"bmc.kepler.service_1","Path":"/bmc/kepler/TestObj1",)"
        R"("Interface":"bmc.kepler.TestInterface1","Property":"TestProp1"},{"Service":"bmc.kepler.service_2",)"
        R"("Path":"/bmc/kepler/TestObj2","Interface":"bmc.kepler.TestInterface2","Property":"TestProp2"})"
        R"#(],"expressions":["expr($1 + $2 * 3)"],"Default":3.14})#");
    sync_info = csr_utils::get_sync_property_info("", "", {});
    EXPECT_EQ(sync_info, R"({"properties":[]})");
}